package com.xjoyt.pay.controllers;

import java.io.OutputStream;
import java.io.PrintWriter;
import java.lang.reflect.Field;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.time.DateFormatUtils;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.util.HSSFColor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import com.google.gson.Gson;
import com.xjoyt.pay.constants.DateConstant;
import com.xjoyt.pay.core.excel.ConvertExcelCell;
import com.xjoyt.pay.dto.ExecuteResult;

public abstract class AbstractController {

	@Value("${spring.profiles.active}")
	protected String active;

	protected static final Logger logger = LoggerFactory.getLogger(AbstractController.class);

	protected boolean isProduct() {
		return StringUtils.isNotBlank(active)
				&& ("prod".equals(active.toLowerCase()) || "product".equals(active.toLowerCase()));
	}

	protected boolean isDeveloper() {
		return StringUtils.isNotBlank(active) && "dev".equals(active.toLowerCase());
	}

	protected String toJson(Object obj) {
		if (obj == null) {
			return null;
		}
		Gson gson = new Gson();
		String json = gson.toJson(obj);
		return json;
	}

	protected <T> T toObject(String json, Class<T> cls) {
		Gson gson = new Gson();
		return gson.fromJson(json, cls);
	}

	protected String getRequestPath() {
		HttpServletRequest request = getHttpServletRequest();
		String path = request.getContextPath();
		String url = request.getScheme() + "://" + request.getServerName();
		int port = request.getServerPort();
		if (port != 80 && port != 443) {
			url += ":" + port;
		}
		url += path;
		return url;
	}

	protected HttpSession getSession() {
		return getHttpServletRequest().getSession();
	}

	protected ServletRequestAttributes getServletRequestAttributes() {
		ServletRequestAttributes attrs = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
		return attrs;
	}

	protected HttpServletRequest getHttpServletRequest() {
		return getServletRequestAttributes().getRequest();
	}

	protected HttpServletResponse getHttpServletResponse() {
		return getServletRequestAttributes().getResponse();
	}

	@ExceptionHandler
	public void exception(HttpServletRequest request, HttpServletResponse response, Exception e) {
		logger.error("服务器发生错误", e);
		StringBuilder builder = new StringBuilder();
		builder.append("\r\n\r\n");
		builder.append("=======================ERROR============================\r\n");
		builder.append(
				"DateTime : " + DateFormatUtils.format(new Date(), DateConstant.DATE_TIME_FORMAT_PATTERN) + "\r\n");
		builder.append("URI : [" + request.getRequestURI() + "]\r\n");

		Map<String, String[]> parameters = request.getParameterMap();
		for (Entry<String, String[]> entry : parameters.entrySet()) {
			String key = entry.getKey();
			builder.append("parameter : [" + key + " : " + request.getParameter(key) + "]\r\n");
		}

		builder.append("exception : [" + e.toString() + "]\r\n");
		e.printStackTrace();
		builder.append("========================================================\r\n");
		builder.append("\r\n\r\n");
		System.out.println(builder.toString());
		logger.error(builder.toString());
		response.setCharacterEncoding("UTF-8");
		response.setContentType("application/json; charset=utf-8");
		try (PrintWriter writer = response.getWriter()) {
			Gson gson = new Gson();
			String json = gson.toJson(ExecuteResult.fail("服务器发生错误"));
			writer.write(json);
		} catch (Exception ex) {
			// TODO Auto-generated catch block
			ex.printStackTrace();
		}
	}

	protected <T> void exportExcel(HttpServletResponse response, List<T> src, Map<String, String> title) {

		// if (CollectionUtils.isEmpty(src)) {
		// return;
		// }
		//
		// try (HSSFWorkbook wb = new HSSFWorkbook()) {
		// HSSFSheet sheet = wb.createSheet("sheet1");
		// int i = 0;
		// if (title != null && title.size() > 0) {
		// HSSFRow row = sheet.createRow(i);
		// i++;
		// int j = 0;
		// for (Entry<String, String> entry : title.entrySet()) {
		// HSSFCell cell = row.createCell(j);
		// j++;
		// cell.setCellValue(entry.getKey());
		// }
		// }
		//
		// for (T t : src) {
		// HSSFRow row = sheet.createRow(i);
		// i++;
		// Class<?> cls = t.getClass();
		// if (title != null && title.size() > 0) {
		// int j = 0;
		// for (Entry<String, String> entry : title.entrySet()) {
		// String value = entry.getValue();
		// HSSFCell cell = row.createCell(j);
		// j++;
		// try {
		// Field field = cls.getField(value);
		//
		// Object val = field.get(t);
		// if (val == null)
		// continue;
		//
		// cell.setCellValue(val.toString());
		// } catch (Exception e) {
		// e.printStackTrace();
		// }
		// }
		// } else {
		// int j = 0;
		// for (Field field : cls.getFields()) {
		// HSSFCell cell = row.createCell(j);
		// j++;
		// try {
		// Object val = field.get(t);
		// if (val == null) {
		// continue;
		// }
		// cell.setCellValue(val.toString());
		// } catch (Exception e) {
		// e.printStackTrace();
		// }
		// }
		// }
		// }
		//
		// response.setContentType("application/ms-excel");
		// try (OutputStream out = response.getOutputStream()) {
		// wb.write(out);
		// out.flush();
		// }
		// } catch (Exception e) {
		// e.printStackTrace();
		// logger.error(e.toString());
		// }
		exportExcel(response, src, title, null);
	}

	protected <T> void exportExcel(HttpServletResponse response, List<T> src, Map<String, String> title,
			Map<String, ConvertExcelCell> convert) {
		if (CollectionUtils.isEmpty(src)) {
			return;
		}

		try (HSSFWorkbook wb = new HSSFWorkbook()) {
			HSSFSheet sheet = wb.createSheet("sheet1");
			sheet.setColumnWidth(0, 8000);
			sheet.setColumnWidth(1, 5500);
			sheet.setColumnWidth(2, 5000);
			sheet.setColumnWidth(3, 5000);
			sheet.setColumnWidth(4, 4000);
			sheet.setColumnWidth(5, 5000);
			sheet.setColumnWidth(6, 5000);
			HSSFCellStyle style = wb.createCellStyle();
			HSSFFont font = wb.createFont();
			font.setColor(HSSFColor.HSSFColorPredefined.BLUE.getIndex());

			style.setFont(font);
			int i = 0;
			if (title != null && title.size() > 0) {
				HSSFRow row = sheet.createRow(i);
				i++;
				int j = 0;
				for (Entry<String, String> entry : title.entrySet()) {
					HSSFCell cell = row.createCell(j);

					j++;
					cell.setCellValue(entry.getKey());
				}
			}

			for (T t : src) {
				HSSFRow row = sheet.createRow(i);
				i++;
				Class<?> cls = t.getClass();
				int j = 0;
				for (Entry<String, String> entry : title.entrySet()) {
					String key = entry.getKey();
					String value = entry.getValue();
					HSSFCell cell = row.createCell(j);
					j++;
					try {
						Field field = cls.getField(value);
						Object val = field.get(t);
//<<<<<<< HEAD
						if (val == null)
							continue;
						if(key == "支付状态"){
							System.out.println();
						}
//=======

//>>>>>>> 79fe862dfabe2eee48c456d0a9a4d3651198d9ca
						if (convert != null && convert.containsKey(key) && convert.get(key) != null)
							cell.setCellValue(convert.get(key).convert(val));
						else {
							cell.setCellValue(val.toString());
						}
						cell.setCellStyle(style);
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
			}

			response.setContentType("application/ms-excel");
			try (OutputStream out = response.getOutputStream()) {
				wb.write(out);
				out.flush();
			}
		} catch (Exception e) {
			e.printStackTrace();
			logger.error(e.toString());
		}
	}
}
